﻿using Coldairarrow.Entity.Base_Manage;
using Coldairarrow.Entity.DTO;
using Coldairarrow.Entity.PB;
using Coldairarrow.IBusiness;
using Coldairarrow.Util;
using EFCore.Sharding;
using LinqKit;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Dynamic.Core;
using System.Linq.Expressions;
using System.Threading.Tasks;

namespace Coldairarrow.Business.PB
{
    public partial class PB_MaterialPriceBusiness : BaseBusiness<PB_MaterialPrice>, IPB_MaterialPriceBusiness, ITransientDependency
    {
        readonly IOperator _operator;
        public PB_MaterialPriceBusiness(IDbAccessor db, IOperator @operator)
            : base(db)
        {
            _operator = @operator;
        }

        #region 外部接口

        public async Task<PageResult<PB_MaterialPrice>> GetDataListAsync(PageInput<ConditionDTO> input)
        {
            var q = GetIQueryable();
            var where = LinqHelper.True<PB_MaterialPrice>();
            var search = input.Search;

            //筛选
            if (!search.Condition.IsNullOrEmpty() && !search.Keyword.IsNullOrEmpty())
            {
                var newWhere = DynamicExpressionParser.ParseLambda<PB_MaterialPrice, bool>(
                    ParsingConfig.Default, false, $@"{search.Condition}.Contains(@0)", search.Keyword);
                where = where.And(newWhere);
            }

            return await q.Where(where).GetPageResultAsync(input);
        }

        public async Task<PB_MaterialPrice> GetTheDataAsync(string id)
        {
            return await GetEntityAsync(id);
        }

        public async Task AddDataAsync(PB_MaterialPrice data)
        {
            await InsertAsync(data);
        }

        public async Task UpdateDataAsync(PB_MaterialPrice data)
        {
            await UpdateAsync(data);
        }

        public async Task DeleteDataAsync(List<string> ids)
        {
            await DeleteAsync(ids);
        }

        public async Task<PageResult<PB_MaterialPriceDTO>> GetDataListDTOAsync(PageInput<ConditionDTO> input)
        {
            var search = input.Search;
            Expression<Func<PB_MaterialPrice, Base_Department,PB_ProcecureSub,PB_Material, PB_MaterialPriceDTO>> select = (a, b,c,d) => new PB_MaterialPriceDTO
            {
             
                //DeptidNameet=b.Name,
                //MaterialidName=d.Name,
                ProcecureSubidName=c.Name
            };
            select = select.BuildExtendSelectExpre();
            var q = from a in GetIQueryable().AsExpandable()
                    join b in Db.GetIQueryable<Base_Department>() on a.Deptid equals b.Id into ab
                    from b in ab.DefaultIfEmpty()
                    join c in Db.GetIQueryable<PB_ProcecureSub>() on a.ProcecureSubid equals c.Id into ac
                    from c in ac.DefaultIfEmpty()
                    join d in Db.GetIQueryable<PB_Material>() on a.Materialid equals d.Id into ad
                    from d in ad.DefaultIfEmpty()
                    select @select.Invoke(a, b,c,d);
            //筛选
            if (!search.Condition.IsNullOrEmpty() && !search.Keyword.IsNullOrEmpty())
            {
                var keyword = $"%{search.Keyword}%";
                q = q.Where(x => EF.Functions.Like(search.Condition, keyword));
            }
            return await q.GetPageResultAsync(input);
        }

        /// <summary>
        /// 保存计件单价
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        public async Task SaveMaterialPriceAsync(MaterialPriceDTO data)
        {
            string sqlMain = @"select * from PB_MaterialPrice where Materialid='" + data.Materialid + "' and ProcecureSubid='" + data.ProcecureSubid + "' and Deptid='" + data.Deptid + "' and WorkDate BETWEEN '" + data.StartDate + "' and '" + data.EndDate + "'";
            List<PB_MaterialPrice> mplist = await Db.GetListBySqlAsync<PB_MaterialPrice>(sqlMain);
            if (mplist.Count > 0)
            {
                throw new BusException("当前时段已维护单价不能重复维护");
            }

            DateTime StartDate = Convert.ToDateTime(data.StartDate);
            DateTime EndDate = Convert.ToDateTime(data.EndDate);
            TimeSpan ts = EndDate.Subtract(StartDate);
            int days = ts.Days + 1;
            List<PB_MaterialPrice> listdata = new List<PB_MaterialPrice>();
            for (int i = 0; i < days; i++)
            {
                PB_MaterialPrice pdata = new PB_MaterialPrice();
                pdata.Id = IdHelper.GetId();
                pdata.CreateTime = DateTime.Now;
                pdata.CreatorId = _operator.UserId;
                pdata.CreatorRealName = _operator.Property?.RealName;
                pdata.Deleted = false;
                pdata.Materialid = data.Materialid;
                pdata.ProcecureSubid = data.ProcecureSubid;
                pdata.Deptid = data.Deptid;
                pdata.UnitPrice = data.UnitPrice;
                pdata.WorkDate = StartDate.AddDays(i);
                pdata.PricingMethod = data.PricingMethod;
                listdata.Add(pdata);
            }
            await Db.InsertAsync<PB_MaterialPrice>(listdata);
        }

        /// <summary>
        /// 调整计件单价
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        public async Task UpdateMaterialPriceAsync(MaterialPriceDTO data)
        {
            //验证是否存在
            string sqlMain = @"select * from PB_MaterialPrice where Materialid='" + data.Materialid + "' and ProcecureSubid='" + data.ProcecureSubid + "' and Deptid='" + data.Deptid + "' and WorkDate BETWEEN '" + data.StartDate + "' and '" + data.EndDate + "'";
            List<PB_MaterialPrice> mplist = await Db.GetListBySqlAsync<PB_MaterialPrice>(sqlMain);
            if (mplist.Count == 0)
            {
                throw new BusException("当前时段未发现符合条件的数据");
            }
            //修改价格
            string sqlUpd = @"update PB_MaterialPrice set UnitPrice='"+data.UnitPrice+"' where Materialid='" + data.Materialid + "' and ProcecureSubid='" + data.ProcecureSubid + "' and Deptid='" + data.Deptid + "' and WorkDate BETWEEN '" + data.StartDate + "' and '" + data.EndDate + "'";
            await Db.ExecuteSqlAsync(sqlUpd);
        }

        /// <summary>
        /// 调整劳务单价
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        public async Task UpdateLabourPriceAsync(MaterialPriceDTO data)
        {
            //验证是否存在
            string sqlMain = @"select * from PB_MaterialPrice where ProcecureSubid='" + data.ProcecureSubid + "' and Deptid='" + data.Deptid + "' and WorkDate BETWEEN '" + data.StartDate + "' and '" + data.EndDate + "'";
            List<PB_MaterialPrice> mplist = await Db.GetListBySqlAsync<PB_MaterialPrice>(sqlMain);
            if (mplist.Count == 0)
            {
                throw new BusException("当前时段未发现符合条件的数据");
            }
            //修改价格
            string sqlUpd = @"update PB_MaterialPrice set UnitPrice='" + data.UnitPrice + "' where ProcecureSubid='" + data.ProcecureSubid + "' and Deptid='" + data.Deptid + "' and WorkDate BETWEEN '" + data.StartDate + "' and '" + data.EndDate + "'";
            await Db.ExecuteSqlAsync(sqlUpd);
        }

        /// <summary>
        /// 查询物料计件单价
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<PageResult<MaterialPriceListDTO>> GetMaterialPriceListAsync(PageInput<MaterialPriceConditionDTO> input)
        {
            var search = input.Search;
            var where = LinqHelper.True<MaterialPriceListDTO>();
            Expression<Func<PB_MaterialPrice, PB_Material, PB_ProcecureSub, Base_Department, MaterialPriceListDTO>> select = (a, b, c, d) => new MaterialPriceListDTO
            {
                MaterialName = b.Name,
                MaterialCode = b.Code,
                MaterialSpec = b.Spec,
                ProcecureSubName = c.Name,
                DeptName = d.Name
            };
            select = select.BuildExtendSelectExpre();
            var q = from a in GetIQueryable().AsExpandable()
                    join b in Db.GetIQueryable<PB_Material>() on a.Materialid equals b.Id into ab
                    from b in ab.DefaultIfEmpty()
                    join c in Db.GetIQueryable<PB_ProcecureSub>() on a.ProcecureSubid equals c.Id into ac
                    from c in ac.DefaultIfEmpty()
                    join d in Db.GetIQueryable<Base_Department>() on a.Deptid equals d.Id into ad
                    from d in ad.DefaultIfEmpty()
                    select @select.Invoke(a, b, c, d);
            //筛选
            if (!search.Keyword.IsNullOrEmpty())
            {
                var newWhere = DynamicExpressionParser.ParseLambda<MaterialPriceListDTO, bool>(
                    ParsingConfig.Default, false, $@"MaterialName.Contains(@0) or MaterialCode.Contains(@0)", search.Keyword);
                where = where.And(newWhere);
            }
            if (!search.Deptid.IsNullOrEmpty())
            {
                where = where.And(x => x.Deptid == search.Deptid);
            }
            if (!search.ProcecureSubid.IsNullOrEmpty())
            {
                where = where.And(x => x.ProcecureSubid == search.ProcecureSubid);
            }
            if (!search.StartDate.IsNullOrEmpty() && !search.EndDate.IsNullOrEmpty())
            {
                DateTime StartDate = Convert.ToDateTime(search.StartDate);
                DateTime EndDate = Convert.ToDateTime(search.EndDate).AddDays(1).AddSeconds(-1);
                where = where.And(x => x.WorkDate >= StartDate && x.WorkDate <= EndDate);
            }
            return await q.Where(where).GetPageResultAsync(input);
        }

        #endregion

        #region 私有成员

        #endregion
    }
}